#include "RtmpMuxerImpl.h"

#include <windows.h>
#include "avpacket.h"
#include "rtmpsendtask.h"
#include "TimestampBulider.h"
#include "avpacket.h"
#include "AsynchExecTask.h"
RtmpSendTask::RtmpSendTask()
    : m_audio_send_bytes(0)
    , m_video_send_bytes(0)
    , m_data_send_bytes(0)
    , videoSH(0)
    , audioSH(0)
    , m_fps(0)
	, m_oEvent(0)
{

}

RtmpSendTask::~RtmpSendTask()
{
}

void RtmpSendTask::set_url(const string &url)
{
    m_oUrl = url;
}

void RtmpSendTask::set_event_handle(AsynchExecTask *pEvent)
{
	m_oEvent = pEvent;
}

int RtmpSendTask::close()
{
	releaseAvPacket();//释放并 丢弃待发送数据
	int nthread = thr_count();
	if (nthread > 0)
	{
		for (int i = 0; i < nthread; i++)
			putq(std::string(""));

		Sleep(80);

		if (m_rtmp_muxer)
			m_rtmp_muxer->close_socket();
		wait();
	}
	if (videoSH)
		delete videoSH;
	videoSH = NULL;

	if (audioSH)
		delete audioSH;
	audioSH = NULL;

    return true;
}

bool RtmpSendTask::receive_handler(const char *data, int size)
{
    putq(std::string(data,size));
    return true;
}

int RtmpSendTask::svc()
{
    WORD versionRequested;
    WSADATA wsaData;
    versionRequested = MAKEWORD(1, 1);

    if(WSAStartup(versionRequested, &wsaData))
        return false;

    m_rtmp_muxer =  new RtmpMuxerImpl;
    m_rtmp_muxer->setRtmpUrl(m_oUrl);
    int ret = m_rtmp_muxer->start();//
    if (ret != TRUE)
    {

        m_rtmp_muxer->stop();  //连接失败
        delete m_rtmp_muxer;
		m_rtmp_muxer = NULL;
		
		if (m_oEvent)
			m_oEvent->PutOnConnectErr(std::string("连接 或者创建流 失败"));//

        return false;
    }
	if (m_oEvent)
	{
		if (videoSH)
			m_oEvent->PutOnConnectSuccess(std::string("2"));
		else
			m_oEvent->PutOnConnectSuccess(std::string("1"));
	}
		

    ret = service(*m_rtmp_muxer);
    m_rtmp_muxer->stop();
    delete m_rtmp_muxer;
	m_rtmp_muxer = NULL;
    WSACleanup();
	
	if (m_oEvent && (ret == 100))
		m_oEvent->PutOnNetDisconn(std::string("发送失败 断开连接"));//
    return true;
}

void RtmpSendTask::releaseAvPacket()
{
	std::string str = "";
	while (getq(str, false))
	{
		if (str != "")
		{
			AVPacket  * avPacket = (*(AVPacket **)str.data());
			delete avPacket;//释放 包内存
		}
	}
}

int RtmpSendTask::service(RtmpMuxerImpl &rtmp_muxer)
{
     int ret = 0;
//     MStream metadata_body;
//     if ((ret = sendMetadata(rtmp_muxer, metadata_body)) != 0) {
//         return ret;
//     }

    if (videoSH)
    {
        MStream &data = videoSH->data;
        if (rtmp_muxer.addH264(data, videoSH->dts) != TRUE )
            return 100;
    }

    if (audioSH)
    {
        MStream &data = audioSH->data;
        if (rtmp_muxer.addAAC(data, audioSH->dts) != TRUE )
            return 100;
    }

    std::string str ="";
    while(getq(str))
    {
        if (str=="") break;

        AVPacket  * avPacket = (*(AVPacket **)str.data());
        while (!avPacket->has_encoded)
        {
            Sleep(20);
        }

        MStream &data = avPacket->data;

        if ((avPacket->pktType == Packet_Video)&&(!data.empty()))
        {
            if (rtmp_muxer.addH264(data, avPacket->dts) != TRUE )
            {
                 ret = 100;
                 break;
            }

             m_video_send_bytes += data.size();
             m_fps += 1;
        } else if ((avPacket->pktType == Packet_Audio)&&(!data.empty()))
        {
            if (rtmp_muxer.addAAC(data, avPacket->dts) != TRUE )
            {
                ret = 100;
                break;
            }

            m_audio_send_bytes += data.size();
        }

        m_data_send_bytes += data.size();

        delete avPacket;//释放 包内存
    }
    return ret;
}

void RtmpSendTask::Init(string &VideoSh, string &VideoSei, string &AudioSh)
{
    if(audioSH)
        delete audioSH;
    audioSH = new AudioPacket;
    audioSH->dts = 0;
    audioSH->has_encoded = true;
    audioSH->data.writeString(AudioSh.data(),AudioSh.size() );


    if(videoSH)
        delete videoSH;
	videoSH = NULL;

	if (!VideoSh.empty())
	{
		videoSH = new VideoPacket;
		videoSH->dts = 0;
		videoSH->has_encoded = true;
		videoSH->data.writeString(VideoSh.data(), VideoSh.size());
	}
   
	if (!VideoSei.empty())
	{
		VideoPacket *videoSei = new VideoPacket;
		videoSei->dts = 0;
		videoSei->has_encoded = true;
		videoSei->data.writeString(VideoSei.data(), VideoSei.size());
		putq(string((char*)&videoSei, sizeof(videoSei)));
	}
}

int RtmpSendTask::sendMetadata(RtmpMuxerImpl &muxer, MStream &body)
{
    FlvMetaData *meta = new FlvMetaData;
    meta->audiocodecid = CODECID_AAC;
    meta->audiodatarate = 44100;
    meta->audiodelay = 0;
    meta->audiosamplerate = 128000;
    meta->audiosamplesize = 32;
    meta->canSeekToEnd = false;
    meta->duration = 0;
    meta->filesize = 0;
    meta->framerate = 10;
    meta->height = 480;
    meta->stereo = false;
    meta->videocodecid = CODECID_H264;
    meta->videodatarate = 800;
    meta->width = 640;
    meta->creationdate = "";// QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss").toStdString();

    if ((muxer.setMetaData(*meta, body)) != TRUE)
    {
        delete meta;
        return 100;
    }
    delete meta;
    return 0;
}

